/**
 * 复制所有必要的node_modules依赖到指定目录
 * 用于确保打包后的应用能找到所有需要的依赖
 * 只过滤Vue前端相关和Puppeteer浏览器
 */

const fs = require("fs-extra")
const path = require("path")
const childProcess = require("child_process")

// 项目根目录
const rootDir = path.resolve(__dirname, "..")
// 目标目录
const targetDir = path.join(rootDir, "dist-electron", "node_modules")
// 源node_modules目录
const sourceDir = path.join(rootDir, "node_modules")

// 明确排除的包列表 - 只排除前端和浏览器相关
const excludedPackages = [
  // Puppeteer 浏览器和安装脚本
  "puppeteer/lib/cjs/puppeteer/node/install.js",
  "puppeteer/.local-chromium",
  "puppeteer/.local-firefox",
  ".local-chromium",
  ".local-firefox",
  "chromium",

  // 前端框架相关
  "vue",
  "@vue",
  "vue-tsc",
  "@vitejs",
  "vite-plugin",
  "unplugin",
  "element-plus",
  "pinia",
  "vue-router",
  "pinia-plugin-persistedstate",

  // CSS相关
  "normalize.css",
  "less",
  "sass",
  "postcss",
  "tailwindcss",

  // 纯前端工具
  "vite",
  "@vite",
  "@rollup",
  "rollup",
  "esbuild"
]

// 保证一定会被复制的核心包
const coreDependencies = [
  "electron-store",
  "conf",
  "ajv",
  "fast-uri",  // 新增，处理ajv依赖
  "uri-js",    // 新增，处理ajv依赖
  "puppeteer-core",
  "puppeteer-extra",
  "puppeteer-extra-plugin-stealth",
  "p-limit",
  "p-try",
  "p-locate",
  "locate-path",
  "find-up",
  "pkg-up",
  "puppeteer",  // 依然复制，但会排除浏览器部分
  "mqtt",
  "axios",
  "fs-extra"
]

// 复制整个node_modules目录，但跳过排除的包
function copyNodeModules() {
  console.log("复制node_modules依赖...")

  // 确保目标目录存在
  fs.ensureDirSync(targetDir)

  // 获取node_modules中的所有顶级目录
  const entries = fs.readdirSync(sourceDir, { withFileTypes: true })

  // 过滤出目录，排除排除列表中的
  const packagesToCopy = entries
    .filter(entry => entry.isDirectory())
    .map(entry => entry.name)
    .filter(name => !excludedPackages.some(excluded =>
      name === excluded || name.startsWith(excluded + "/")))

  console.log(`找到 ${packagesToCopy.length} 个要复制的包`)

  // 复制包
  let copied = 0
  let errors = 0

  for (const pkg of packagesToCopy) {
    const source = path.join(sourceDir, pkg)
    const target = path.join(targetDir, pkg)

    try {
      // 使用自定义复制函数，跳过大型浏览器目录
      copyDirExcludeBrowsers(source, target)
      console.log(`✅ 已复制: ${pkg}`)
      copied++
    } catch (err) {
      console.error(`❌ 复制 ${pkg} 时出错:`, err)
      errors++
    }
  }

  return { copied, errors }
}

// 自定义复制函数，排除浏览器相关目录
function copyDirExcludeBrowsers(src, dest) {
  // 确保目标目录存在
  fs.ensureDirSync(dest)

  // 获取源目录内容
  const entries = fs.readdirSync(src, { withFileTypes: true })

  for (const entry of entries) {
    const srcPath = path.join(src, entry.name)
    const destPath = path.join(dest, entry.name)

    // 检查是否是要排除的目录/文件
    const relativePath = path.relative(sourceDir, srcPath)
    if (shouldExclude(relativePath)) {
      console.log(`⏩ 跳过: ${relativePath}`)
      continue
    }

    if (entry.isDirectory()) {
      // 递归复制目录
      copyDirExcludeBrowsers(srcPath, destPath)
    } else {
      // 复制文件
      fs.copyFileSync(srcPath, destPath)
    }
  }
}

// 检查路径是否应该被排除
function shouldExclude(relativePath) {
  // 排除浏览器和前端相关路径
  if (
    relativePath.includes('.local-chromium') ||
    relativePath.includes('.local-firefox') ||
    relativePath.includes('node_modules/puppeteer/.local-') ||
    relativePath.includes('.bin/') && (
      relativePath.includes('vite') ||
      relativePath.includes('vue') ||
      relativePath.includes('rollup') ||
      relativePath.includes('esbuild')
    )
  ) {
    return true
  }

  // 检查是否在排除列表中
  return excludedPackages.some(excluded =>
    relativePath === excluded ||
    relativePath.startsWith(excluded + "/") ||
    relativePath.includes(`/node_modules/${excluded}/`)
  )
}

// 确保核心依赖存在
function ensureCoreDependencies() {
  console.log("检查核心依赖...")

  let missing = []

  // 检查每个核心依赖是否存在于目标目录
  for (const dep of coreDependencies) {
    const depPath = path.join(targetDir, dep)
    if (!fs.existsSync(depPath)) {
      missing.push(dep)
    }
  }

  // 如果有缺失的依赖，尝试单独复制
  if (missing.length > 0) {
    console.log(`发现 ${missing.length} 个缺失的核心依赖，尝试复制...`)

    for (const dep of missing) {
      const source = path.join(sourceDir, dep)
      const target = path.join(targetDir, dep)

      if (fs.existsSync(source)) {
        try {
          copyDirExcludeBrowsers(source, target)
          console.log(`✅ 已复制核心依赖: ${dep}`)
        } catch (err) {
          console.error(`❌ 复制核心依赖 ${dep} 时出错:`, err)
        }
      } else {
        console.warn(`⚠️ 核心依赖不存在于源目录: ${dep}`)
      }
    }
  } else {
    console.log("✅ 所有核心依赖都已存在")
  }
}

// 处理特殊包的嵌套依赖
function handleNestedDependencies() {
  console.log("处理特殊嵌套依赖...")

  // 处理conf包的ajv依赖
  const confPath = path.join(targetDir, "conf")
  if (fs.existsSync(confPath)) {
    const confNodeModules = path.join(confPath, "node_modules")
    const sourceConfNodeModules = path.join(sourceDir, "conf", "node_modules")

    if (fs.existsSync(sourceConfNodeModules)) {
      try {
        copyDirExcludeBrowsers(sourceConfNodeModules, confNodeModules)
        console.log("✅ 已复制conf的嵌套依赖")
      } catch (err) {
        console.error("❌ 复制conf嵌套依赖时出错:", err)
      }
    }
  }

  // 特殊处理fast-uri依赖
  const fastUriSource = path.join(sourceDir, "fast-uri")
  const fastUriTargetPaths = [
    path.join(targetDir, "fast-uri"),
    path.join(targetDir, "conf", "node_modules", "fast-uri"),
    path.join(targetDir, "conf", "node_modules", "ajv", "node_modules", "fast-uri")
  ]

  if (fs.existsSync(fastUriSource)) {
    for (const targetPath of fastUriTargetPaths) {
      try {
        fs.ensureDirSync(path.dirname(targetPath))
        copyDirExcludeBrowsers(fastUriSource, targetPath)
        console.log(`✅ 已复制fast-uri到: ${targetPath}`)
      } catch (err) {
        console.error(`❌ 复制fast-uri到 ${targetPath} 时出错:`, err)
      }
    }
  } else {
    console.warn("⚠️ 未找到fast-uri源目录")
  }
}

// 创建electron存根以支持electron-store
function createElectronStub() {
  console.log("创建electron存根...")

  const electronStubDir = path.join(targetDir, "electron")
  fs.ensureDirSync(electronStubDir)

  const electronStubContent = `
/**
 * Electron存根模块
 * 提供electron-store所需的最小接口
 */
const path = require('path');
const os = require('os');

module.exports = {
  app: {
    getPath: function(name) {
      switch(name) {
        case 'userData':
          return path.join(os.homedir(), 'AppData', 'Roaming', 'YourAppName');
        case 'appData':
          return path.join(os.homedir(), 'AppData', 'Roaming');
        case 'home':
          return os.homedir();
        case 'temp':
          return os.tmpdir();
        default:
          return path.join(os.homedir(), 'AppData', 'Roaming', 'YourAppName');
      }
    },
    getName: function() {
      return 'YourAppName';
    },
    getVersion: function() {
      return '1.0.0';
    }
  }
};
`

  fs.writeFileSync(path.join(electronStubDir, "index.js"), electronStubContent)
  console.log("✅ 已创建electron存根模块")

  // 修复electron-store引用
  const electronStorePath = path.join(targetDir, "electron-store")
  if (fs.existsSync(electronStorePath)) {
    const indexPath = path.join(electronStorePath, "index.js")
    if (fs.existsSync(indexPath)) {
      let content = fs.readFileSync(indexPath, 'utf8')

      if (content.includes("require('electron')") && !content.includes("require('../electron')")) {
        // 备份原文件
        fs.writeFileSync(`${indexPath}.backup`, content)

        // 替换electron引用
        content = content.replace("require('electron')", "require('../electron')")
        fs.writeFileSync(indexPath, content)
        console.log("✅ 已修补electron-store引用")
      }
    }
  }
}

// 创建package.json
function createPackageJson() {
  const packageJson = {
    name: "app-dependencies",
    version: "1.0.0",
    description: "Node.js dependencies for the application",
    private: true
  }

  fs.writeFileSync(path.join(targetDir, "package.json"), JSON.stringify(packageJson, null, 2))
  console.log("✅ 已创建package.json")
}

// 主函数
async function main() {
  console.log("开始处理node_modules依赖...")

  // 清空目标目录
  if (fs.existsSync(targetDir)) {
    fs.removeSync(targetDir)
    console.log("已清空目标目录")
  }

  // 复制node_modules
  const { copied, errors } = copyNodeModules()

  // 确保核心依赖存在
  ensureCoreDependencies()

  // 处理嵌套依赖
  handleNestedDependencies()

  // 创建electron存根
  createElectronStub()

  // 创建package.json
  createPackageJson()

  console.log(`\n完成! 已复制 ${copied} 个包, 错误: ${errors} 个`)
  console.log("已排除Vue前端相关依赖和Puppeteer浏览器")
}

main().catch((err) => {
  console.error("处理过程中发生错误:", err)
  process.exit(1)
})
